using System.Collections.Generic;
using LogSystem;
using UnityEngine;

namespace Yoozoo.Gameplay.City
{
    public class CityRealAiAreaManager : CityRealAiContainerManagerBase
    {
        public override Transform RoomRootTran
        {
            get
            {
                return CityRealAiManager.GetInstance().CityRealAiRootTran;
            }
        }

        /// <summary>
        /// key = roomId  value = dic  dicKey = index  value = CityRealAiRoomManager
        /// </summary>
        public Dictionary<int, Dictionary<int, CityRealAiRoomManager>> RoomDic { get; }
        
        public override bool IsLoadComplete
        {
            get
            {
                foreach (var keyValuePair in NpcTypeCtrlDic)
                {
                    foreach (var subKeyValuePair in keyValuePair.Value)
                    {
                        if (!subKeyValuePair.Value.IsLoadComplete)
                        {
                            return false;
                        }
                    }
                }
                
                foreach (var keyValuePair in RoomDic)
                {
                    foreach (var subKeyValuePair in keyValuePair.Value)
                    {
                        if (!subKeyValuePair.Value.IsLoadComplete)
                        {
                            return false;
                        }
                    }
                }

                return true;
            }
        }
        
        /// <summary>
        /// 这里缓存的是所有Area内产生的AreaNpc。
        /// key = RoleId value = dic dic.key = Uid value = npc
        /// </summary>
        public Dictionary<int, Dictionary<int, CityRealAiNpcController>> AllNpcTypeCtrlDic { get; }

        public CityRealAiAreaManager(int containerId) : base(containerId)
        {
            RoomDic = new Dictionary<int, Dictionary<int, CityRealAiRoomManager>>();
            AllNpcTypeCtrlDic = new Dictionary<int, Dictionary<int, CityRealAiNpcController>>();
        }

        public bool ContainsRoom(int roomId, int roomIndex)
        {
            if (RoomDic.TryGetValue(roomId, out var subRoomDic))
            {
                return subRoomDic.ContainsKey(roomIndex);
            }

            return false;
        }

        public CityRealAiRoomManager CreateRoom(int roomId, int roomIndex)
        {
            if (!RoomDic.TryGetValue(roomId, out var roomSubDic))
            {
                roomSubDic = new Dictionary<int, CityRealAiRoomManager>();
                RoomDic.Add(roomId, roomSubDic);
            }

            CityRealAiRoomManager room;
            if (roomId == CityRealAiConst.WallId)
            {
                room = new CityRealAiWallManager(roomId, roomIndex, ContainerId);
            }
            else
            {
                room = new CityRealAiRoomManager(roomId, roomIndex, ContainerId);
            }
            roomSubDic.Add(roomIndex, room);
            
            return room;
        }

        public void AddRoom(CityRealAiRoomManager room)
        {
            if (!RoomDic.TryGetValue(room.ContainerId, out var roomSubDic))
            {
                roomSubDic = new Dictionary<int, CityRealAiRoomManager>();
                RoomDic.Add(room.ContainerId, roomSubDic);
            }

            if (!roomSubDic.ContainsKey(room.BuildIndex))
            {
                roomSubDic.Add(room.BuildIndex, room);
            }
        }

        public void RemoveRoom(int roomId, int roomIndex)
        {
            if (RoomDic.TryGetValue(roomId, out var roomSubDic))
            {
                if (roomSubDic.ContainsKey(roomIndex))
                {
                    roomSubDic.Remove(roomIndex);
                }
            }
        }
        
        public CityRealAiRoomManager TryGetRoom(int roomId, int roomIndex)
        {
            if (RoomDic.TryGetValue(roomId, out var subRoomDic))
            {
                if (subRoomDic.TryGetValue(roomIndex, out var roomMgr))
                {
                    return roomMgr;
                }
            }
            
            return null;
        }

        public CityRealAiRoomManager GetRandomRoom(int roomId)
        {
            if (RoomDic.TryGetValue(roomId, out var subRoomDic))
            {
                if (subRoomDic.Count <= 0)
                {
                    return null;
                }

                var random = Random.Range(0, subRoomDic.Count);
                var index = 0;
                foreach (var keyValuePair in subRoomDic)
                {
                    if (random == index)
                    {
                        return keyValuePair.Value;
                    }

                    index++;
                }
            }
            
            return null;
        }

        public CityRealAiRoomManager GetRoom(int roomId, int roomIndex)
        {
            if (RoomDic.TryGetValue(roomId, out var subRoomDic))
            {
                if (subRoomDic.TryGetValue(roomIndex, out var roomMgr))
                {
                    return roomMgr;
                }
            }
            
            return null;
        }
        
        public CityRealAiNpcController GetNpcCtrlExcludeUid(int roleId, int birthContainerId, List<int> excludeUidList)
        {
            if (AllNpcTypeCtrlDic.TryGetValue(roleId, out var npcCtrlDic))
            {
                foreach (var keyValuePair in npcCtrlDic)
                {
                    if (keyValuePair.Value.BirthContainerId != birthContainerId)
                    {
                        continue;
                    }
                    if (excludeUidList==null || !excludeUidList.Contains(keyValuePair.Value.Uid))
                    {
                        return keyValuePair.Value;
                    }
                }
            }

            return null;
        }

        public CityRealAiEventPointInfo CreateVirtualGoodsCtrl(int uid, int treeId, int eventId, int goodsType, Vector3 position)
        {
            var goodsCfg = _cfgMgr.GetEventPointRoomCfg(goodsType);
            if (goodsCfg.roomId == _cfgMgr.EmptyEventPointRoomCfg.roomId || goodsCfg.goodsList.Length <= 0)
            {
                Debug.LogWarningFormat(LogModule.CityAI, LogLevelType.Develop, "未能找到 虚拟事件集 Id = {0} 的配置，请检查配表", goodsType);
                return null; 
            }
            
            var goods = new CityRealAiGoodsController(ContainerId, this, goodsType);
            goods.UpdateContainer(this);
            
            for (int i = 0; i < goodsCfg.goodsList[0].pointDataList.Length; i++)
            {
                var pointData = goodsCfg.goodsList[0].pointDataList[i];
                pointData.Position = (position + pointData.Position);
                var eventInfo = goods.SetupEventPoint(ref pointData);
                if (eventInfo.EventId == eventId)
                {
                    return eventInfo;
                }
            }

            var key = goodsType + uid * 100;
            GoodsCtrlDic.Add(key, goods);
            return null;
        }

        public void RemoveVirtualGoodsCtrl(int uid, int goodsType)
        {
            var key = goodsType + uid * 100;
            if (GoodsCtrlDic.TryGetValue(key, out var goodsCtrl))
            {
                for (int i = 0; i < goodsCtrl.EventPointList.Count; i++)
                {
                    var eventPoint = goodsCtrl.EventPointList[i];
                    eventPoint.Reset();
                }
                goodsCtrl.EventPointList.Clear();
                GoodsCtrlDic.Remove(key);
            }
        }
        
        public void StartSpecialStateTimer()
        {
            foreach (var keyValuPair in RoomDic)
            {
                foreach (var subKeyValue in keyValuPair.Value)
                {
                    subKeyValue.Value.StartSpecialStateTimer();
                }
            }
        }
        
        public void AddNpcCtrlToAllDic(CityRealAiNpcController npcCtrl)
        {
            if (!AllNpcTypeCtrlDic.TryGetValue(npcCtrl.RoleId, out var ctrlDic))
            {
                ctrlDic = new Dictionary<int, CityRealAiNpcController>();
                AllNpcTypeCtrlDic.Add(npcCtrl.RoleId, ctrlDic);
            }

            if (ctrlDic.ContainsKey(npcCtrl.Uid))
            {
                Debug.LogErrorFormat(LogModule.CityAI, LogLevelType.Develop, "试图向 ContainerId = {0} 的房间或区域内添加一个 Npc UID = {1} 重复角色", ContainerId, npcCtrl.Uid);
                return;
            }
            
            ctrlDic.Add(npcCtrl.Uid, npcCtrl);
        }

        public void RemoveNpcCtrlFromAllDic(CityRealAiNpcController npcCtrl)
        {
            if (!AllNpcTypeCtrlDic.TryGetValue(npcCtrl.RoleId, out var ctrlDic))
            {
                return;
            }

            ctrlDic.Remove(npcCtrl.Uid);
        }
        
        /// <summary>
        /// 获取可以立即触发房间事件的NPC列表
        /// </summary>
        /// <param name="npcType"></param>
        /// <param name="eventTreeId"></param>
        /// <param name="roleType"></param>
        /// <param name="npcNum"></param>
        /// <param name="npcList"></param>
        /// <returns></returns>
        public override bool GetImmediatelyTriggerRoomEventNpcCtrlList(Vector3 linkNpcCfg, int eventTreeId, int needNpcCtrlNum, List<CityRealAiNpcController> npcList, List<List<CityRealAiNpcController>> allNpcList)
        {
            foreach (var keyValuePair in AllNpcTypeCtrlDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    var npcCtrl = subKeyValuePair.Value;
                    if (!CheckImmediatelyTriggerRoomEventNpcCtrlCondition(linkNpcCfg, eventTreeId, npcCtrl))
                    {
                        continue;
                    }
                    
                    bool isContains = false;
                    for (int i = 0; i < allNpcList.Count; i++)
                    {
                        if (allNpcList[i].Contains(npcCtrl))
                        {
                            isContains = true;
                            break;
                        }
                    }

                    if (isContains)
                    {
                        continue;
                    }
                    
                    npcList.Add(npcCtrl);
                    needNpcCtrlNum--;
                    if (needNpcCtrlNum <= 0)
                    {
                        return true;
                    }
                }

            }
            return false;
        }
        
        public void TriggerRoomStateChangeEvent(int buildId, int buildIndex, CityRealRoomStateChangeEvent changeEvent)
        {
            var room = GetRoom(buildId, buildIndex);
            if (room != null)
            {
                room.TriggerRoomStateChangeEvent(changeEvent);
            }
            else
            {
                // Debug.LogWarningFormat(LogModule.CityAI, "未找到 房间对象 ==========>房间 = {0}{1} 内触发 事件 = {2}", buildId,buildIndex,changeEvent);
            }
        }
        
        public override bool CheckNeedAndRunNpc(CityRealAiNpcController npcCtrl)
        {
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    if (subKeyValuePair.Value.CheckNeedAndRunNpc(npcCtrl))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public override void OnPause(bool isPause)
        {
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    subKeyValuePair.Value.OnPause(isPause);
                }
            }

            foreach (var keyValuePair in NpcTypeCtrlDic)
            {
                foreach (var subKeyValurPair in keyValuePair.Value)
                {
                    subKeyValurPair.Value.OnPause(isPause);
                }
            }
        }

        public override void OnUpdate()
        {
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    subKeyValuePair.Value.OnUpdate();
                }
            }
            base.OnUpdate();
        }

        public override void OnResetNpc()
        {
            AllNpcTypeCtrlDic.Clear();
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    subKeyValuePair.Value.OnResetNpc();
                }
            }
            base.OnResetNpc();
        }
        
        public override void OnCloseBusiness()
        {
            base.OnCloseBusiness();
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    subKeyValuePair.Value.OnCloseBusiness();
                }
            }
        }

        public override void Dispose()
        {
            AllNpcTypeCtrlDic.Clear();
            foreach (var keyValuePair in RoomDic)
            {
                foreach (var subKeyValuePair in keyValuePair.Value)
                {
                    subKeyValuePair.Value.Dispose();
                }
            }
            base.Dispose();
        }
    }
}
